/* ----------------------------------------------------------------------------------------------------------------------------------------------- /

Download - 资源加载
修改许可权限 - 戴翔（Nero）

< --- Public Vars ------------------------------------------------------------------------------------------------------------------------------ >

※ 下载线程数（静态）
public static var thread:uint = 5;

※ 提示传递 Loader 本身的常量（静态，常量）
public static const SELF:String = "Download_SELF";

※ 返回加载队列的长度（静态）
public static function get loadingNum():uint

※ 返回等待队列的长度（静态）
public static function get waitingNum():uint

< --- Public Functions ------------------------------------------------------------------------------------------------------------------------ >

※ 开始加载（静态）
public static function to(url:String,onComplete:Function=null,onCompleteParms:Array=null,onError:Function=null,onErrorParms:Array=null,reloadNumber:int=3):Loader
@url:String - 下载资源的URL
@onComplete:Function = null - 下载成功后执行的函数
@onCompleteParms:Array = null - 下载成功后执行函数的参数 ( 想传递Download实例本身请向数组内传入 Download.SELF )
@onError:Function = null - 下载失败时执行的函数
@onErrorParms:Array = null - 下载失败时执行函数的参数 ( 想传递Download实例本身请向数组内传入 Download.SELF )
@reloadNumber:int = 3 - 下载失败后重试下载的次数

※ 返回 Loader 加载百分比（静态，返回 0 - 100）
public static function getPercent(loader:Loader):uint
@loader:Loader - 需要返回加载百分比的 Loader

※ 中断 Loader 加载（静态）
public static function kill(loader:Loader):void
@loader:Loader - 需要中断加载的 Loader

/ ----------------------------------------------------------------------------------------------------------------------------------------------- */
package editor.util{
	
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;

	public class Download{
		
		// --- Config ---------------------------------------------------------------------------------------------------------------------------- //
		
		// 下载线程数
		public static var thread:uint = 6;
		
		// --- Vars ------------------------------------------------------------------------------------------------------------------------------- //
		
		// 提示传递 Loader 本身的常量
		public static const SELF:String = "Download_SELF";
		
		// 正在下载的序列组
		private static var LoadingList:Vector.<Loader> = new Vector.<Loader>();
		private static var LoadingData:Vector.<Object> = new Vector.<Object>();
		
		// 等待下载的序列组
		private static var WaitingList:Vector.<Loader> = new Vector.<Loader>();
		private static var WaitingData:Vector.<Object> = new Vector.<Object>();
		
		// 私有
		private static var LoadURL:URLRequest = new URLRequest();
		
		// --- Functions ------------------------------------------------------------------------------------------------------------------------- //
		
		// 加载资源
		public static function to(url:String,onComplete:Function=null,onCompleteParms:Array=null,onError:Function=null,onErrorParms:Array=null,reloadNumber:int=3):Loader{
			
			// 建立
			var loader:Loader = new Loader();
			var loaderData:Object = {
				Url:url,
				OnComplete:onComplete,
				OnCompleteParms:onCompleteParms,
				OnError:onError,
				OnErrorParms:onErrorParms,
				ReloadNumber:reloadNumber,
				Loading:false
			};
			
			// 添加侦听事件
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,LoadComplete_func);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,LoadError_func);
			
			// 下载线程判断
			if(LoadingList.length<thread){
				
				LoadingList.push(loader);
				LoadingData.push(loaderData);
				LoadURL.url = loaderData.Url;
				loader.load(LoadURL);
				loaderData.Loading = true;
				
			}else{
				
				WaitingList.push(loader);
				WaitingData.push(loaderData);
				
			}
			
			// 返回
			return loader;
		}
		
		// 返回加载队列的长度
		public static function get loadingNum():uint{
			return LoadingList.length;
		}
		
		// 返回等待队列的长度
		public static function get waitingNum():uint{
			return WaitingList.length;
		}
		
		//  返回 Loader 加载百分比
		public static function getPercent(loader:Loader):uint{
			return int(loader.contentLoaderInfo.bytesLoaded/loader.contentLoaderInfo.bytesTotal*100);
		}
		
		// 结束线程
		public static function kill(loader:Loader):void{
			
			// 移除侦听
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,LoadComplete_func);
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,LoadError_func);
			
			// 从正在加载序列移除Loader以及Data
			var index:int = LoadingList.indexOf(loader);
			if(index != -1){
				if(LoadingData[index].Loading){
					// 停止正在下载
					loader.close();
					loader.unloadAndStop();
				}
				LoadingList.splice(index,1);
				LoadingData.splice(index,1);
			}else{
				index = WaitingList.indexOf(loader);
				if(index != -1){
					WaitingList.splice(index,1);
					WaitingList.splice(index,1);
					loader.unloadAndStop();
				}else{
					return;
				}
			}
			
			// 调整加载序列
			if(WaitingList.length>0){
				var length:int = WaitingList.length;
				for(var i:int = 0 ; i<length ; i++){
					if(LoadingList.length<thread){
						
						// 向正在加载序列添加Loader及Data
						LoadURL.url = WaitingData[0].Url;
						WaitingList[0].load(LoadURL);
						WaitingData[0].Loading = true;
						LoadingList.push(WaitingList.shift());
						LoadingData.push(WaitingData.shift());
						
					}else{
						break;
					}
				}
			}
		}
		
		// 载入完成
		private static function LoadComplete_func(evt:Event):void{
			
			// 获得索引
			var index:int = LoadingList.indexOf(LoaderInfo(evt.target).loader);
			
			// 临时变量
			var onComplete:Function = LoadingData[index].OnComplete;
			var onCompleteParms:Array = LoadingData[index].OnCompleteParms;
			
			// 完成运行函数
			if(onComplete != null){
				if(onCompleteParms != null){
					// 带参数运行
					var SelfIndex:int = onCompleteParms.indexOf(Download.SELF);
					if(index != -1){
						onCompleteParms.splice(SelfIndex,1,LoaderInfo(evt.target).loader);
					}
					onComplete.apply(null,onCompleteParms);
				}else{
					// 不带参数运行
					onComplete();
				}
			}
			
			// 提示不在载入中
			LoadingData[index].Loading = false;
			
			// 回收变量
			onComplete = null;
			onCompleteParms = null;
			
			// 结束加载线程
			kill(LoaderInfo(evt.target).loader);
			
		}
		
		// 载入失败
		private static function LoadError_func(evt:Event):void{
			
			// 获得索引
			var index:int = LoadingList.indexOf(LoaderInfo(evt.target).loader);
			
			// 临时变量
			var onError:Function = LoadingData[index].OnError;
			var onErrorParms:Array = LoadingData[index].OnErrorParms;
			
			// 重试下载
			LoadingData[index].ReloadNumber--;
			if(LoadingData[index].ReloadNumber>=0){
				
				LoadURL.url = LoadingData[index].Url;
				LoaderInfo(evt.target).loader.load(LoadURL);
				
			}else{
				
				// 失败运行函数
				if(onError != null){
					if(onErrorParms != null){
						// 带参数运行
						var SelfIndex:int = onErrorParms.indexOf(Download.SELF);
						if(index != -1){
							onErrorParms.splice(SelfIndex,1,LoaderInfo(evt.target).loader);
						}
						onError.apply(null,onErrorParms);
					}else{
						// 不带参数运行
						onError();
					}
				}
				
				// 提示不在载入中
				LoadingData[index].Loading = false;
				
				// 结束加载线程
				kill(LoaderInfo(evt.target).loader);
				
			}
			
			// 回收变量
			onError = null;
			onErrorParms = null;
			
		}
	}
}